﻿using System;
using System.Collections.Generic;
using Basic;

namespace Interface
{
    /// <summary>
    /// 事件系统
    /// </summary>
    public static class EventSystem
    {
        private static Dictionary<int, Action<EventArgsBase>> s_Events;

        static EventSystem()
        {
            s_Events = new Dictionary<int, Action<EventArgsBase>>(128);
        }

        /// <summary>
        /// 输出当前有哪些注册事件
        /// </summary>
        public static void DebugInfo()
        {
            var keys = new List<int>(s_Events.Keys);
            var s = keys.ToReadableString();
            Log.Debug(s);
        }

        /// <summary>
        /// 注册事件
        /// </summary>
        /// <param name="key"></param>
        /// <param name="func"></param>
        public static void Register(int key, Action<EventArgsBase> func)
        {
            Log.Debug("EventSystem.Register key: {0}", key);

            if (func != null)
            {
                if (s_Events.ContainsKey(key))
                {
                    s_Events[key] += func;
                }
                else
                {
                    s_Events[key] = func;
                }
            }
            else
            {
                Log.Error("EventSystem.Register func is null {0}", key);
            }
        }

        /// <summary>
        /// 反注册事件
        /// </summary>
        /// <param name="key"></param>
        /// <param name="func"></param>
        public static void UnRegister(int key, Action<EventArgsBase> func)
        {
            Log.Debug("EventSystem.UnRegister key: {0}", key);

            if (s_Events.ContainsKey(key))
            {
                if (func != null)
                {
                    s_Events[key] -= func;

                    if (s_Events[key] == null)
                    {
                        s_Events.Remove(key);
                    }
                }
                else
                {
                    Log.Error("EventSystem.UnRegister func is null {0}", key);
                }
            }
            else
            {
                Log.Error("EventSystem.UnRegister key: {0}", key);
            }
        }

        /// <summary>
        /// 无参数事件
        /// </summary>
        /// <param name="key"></param>
        public static void FireEvent0(int key)
        {
            var args = EventArgs0.Alloc();
            FireEvent(key, args);
            EventArgs0.OnUseEnd(args);
        }

        /// <summary>
        /// 一参数事件
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="key"></param>
        /// <param name="p1"></param>
        public static void FireEvent1<T1>(int key, T1 p1)
        {
            var args = EventArgs1<T1>.Alloc();
            args.Set(p1);
            FireEvent(key, args);
            EventArgs1<T1>.OnUseEnd(args);
        }

        /// <summary>
        /// 两参数事件
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="key"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        public static void FireEvent2<T1, T2>(int key, T1 p1, T2 p2)
        {
            var args = EventArgs2<T1, T2>.Alloc();
            args.Set(p1, p2);
            FireEvent(key, args);
            EventArgs2<T1, T2>.OnUseEnd(args);
        }

        /// <summary>
        /// 三参数事件
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <param name="key"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        public static void FireEvent3<T1, T2, T3>(int key, T1 p1, T2 p2, T3 p3)
        {
            var args = EventArgs3<T1, T2, T3>.Alloc();
            args.Set(p1, p2, p3);
            FireEvent(key, args);
            EventArgs3<T1, T2, T3>.OnUseEnd(args);
        }

        /// <summary>
        /// 四参数事件
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <typeparam name="T4"></typeparam>
        /// <param name="key"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        public static void FireEvent4<T1, T2, T3, T4>(int key, T1 p1, T2 p2, T3 p3, T4 p4)
        {
            var args = EventArgs4<T1, T2, T3, T4>.Alloc();
            args.Set(p1, p2, p3, p4);
            FireEvent(key, args);
            EventArgs4<T1, T2, T3, T4>.OnUseEnd(args);
        }

        private static void FireEvent(int key, EventArgsBase args)
        {
            if (s_Events.ContainsKey(key))
            {
                try
                {
                    Action<EventArgsBase> action;
                    if (s_Events.TryGetValue(key, out action))
                    {
                        if (action != null)
                        {
                            action(args);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("EventSystem.FireEvent exception: {0} {1}", key, ex);
                }
            }
        }
    }
}
